home *** CD-ROM | disk | FTP | other *** search
Oberon Text | 1990-01-01 | 5.6 KB | 152 lines |
- Syntax10.Scn.Fnt
- MODULE Swarm; (* MB 25.1.90 *)
- IMPORT
- Oberon, Display, Viewers, Input, Texts, Display1;
- CONST
- Border = 50;
- BeeVel = 11;
- WaspVel = 12;
- MaxWasps = 10;
- MaxBees = 500;
- TYPE
- Point = RECORD
- x, y: INTEGER
- END;
- Insect = RECORD
- pos: ARRAY 3 OF Point;
- vx, vy: INTEGER
- END;
- VAR
- Wasps: ARRAY MaxWasps OF Insect;
- Bees: ARRAY MaxBees OF Insect;
- seed: LONGINT;
- NrWasps, NrBees, Delay, WaspAcc, BeeAcc: INTEGER;
- firstTime: BOOLEAN;
- F: Display.Frame;
- PROCEDURE random(): INTEGER;
- BEGIN seed := (seed + 773)*13 MOD 99991; RETURN SHORT(seed MOD 32749)
- END random;
- PROCEDURE Rand(x: INTEGER): INTEGER;
- BEGIN RETURN random() MOD x - x DIV 2
- END Rand;
- PROCEDURE Wait(d: LONGINT);
- VAR t, t1: LONGINT;
- BEGIN
- t := Oberon.Time();
- REPEAT t1 := Oberon.Time() UNTIL t+d <= t1
- END Wait;
- PROCEDURE InitWasp(VAR Wasp: Insect);
- BEGIN
- Wasp.pos[0].x := Border + random() MOD (Display.Width-2*Border);
- Wasp.pos[0].y := Border + random() MOD (Display.Height-2*Border);
- Wasp.pos[1] := Wasp.pos[0];
- Wasp.vx := 0; Wasp.vy := 0
- END InitWasp;
- PROCEDURE InitBee(VAR Bee: Insect);
- VAR j: INTEGER;
- BEGIN
- j := random() MOD Display.Width; Bee.pos[0].x := j; Bee.pos[1].x := j;
- j := random() MOD Display.Height; Bee.pos[0].y := j; Bee.pos[1].y := j;
- Bee.vx := Rand(7); Bee.vy := Rand(7)
- END InitBee;
- PROCEDURE InitSwarm;
- VAR i: INTEGER;
- BEGIN
- seed := Oberon.Time() MOD 231; (*DIM(Wasps, NrWasps); DIM(Bees, NrBees);*)
- NEW(F); F.X := 0; F.Y := 0; F.W := Display.Width; F.H := Display.Height; firstTime := TRUE;
- i := 0; WHILE i < NrWasps DO InitWasp(Wasps[i]); INC(i) END;
- i := 0; WHILE i < NrBees DO InitBee(Bees[i]); INC(i) END
- END InitSwarm;
- PROCEDURE Age(VAR i: Insect);
- BEGIN i.pos[2] := i.pos[1]; i.pos[1] := i.pos[0]
- END Age;
- PROCEDURE BoundSpeed(VAR i: Insect; limit: INTEGER);
- BEGIN
- IF i.vx > limit THEN i.vx := limit ELSIF i.vx < -limit THEN i.vx := -limit END;
- IF i.vy > limit THEN i.vy := limit ELSIF i.vy < -limit THEN i.vy := -limit END
- END BoundSpeed;
- PROCEDURE AccelerateWasp(VAR Wasp: Insect);
- BEGIN
- Wasp.vx := Wasp.vx+Rand(WaspAcc); Wasp.vy := Wasp.vy+Rand(WaspAcc);
- BoundSpeed(Wasp, WaspVel)
- END AccelerateWasp;
- PROCEDURE ReflectWasp(VAR Wasp: Insect);
- BEGIN
- IF (Wasp.pos[0].x < Border) OR (Wasp.pos[0].x > Display.Width-Border-1) THEN
- Wasp.vx := -Wasp.vx; INC(Wasp.pos[0].x, Wasp.vx)
- END;
- IF (Wasp.pos[0].y < Border) OR (Wasp.pos[0].y > Display.Height-Border-1) THEN
- Wasp.vy := -Wasp.vy; INC(Wasp.pos[0].y, Wasp.vy)
- END
- END ReflectWasp;
- PROCEDURE AccelerateBee(VAR Bee: Insect);
- VAR dx, dy, distance, dx1, dy1, distance1, i: INTEGER;
- BEGIN
- i := 0; distance := 10000;
- WHILE i < NrWasps DO
- dx1 := Wasps[i].pos[1].x-Bee.pos[1].x; dy1 := Wasps[i].pos[1].y-Bee.pos[1].y; distance1 := ABS(dx1)+ABS(dy1);
- IF distance1 < distance THEN dx := dx1; dy := dy1; distance := distance1 END;
- INC(i)
- END;
- IF distance = 0 THEN distance := 1 END;
- Bee.vx := Bee.vx + (dx*BeeAcc) DIV distance; Bee.vy := Bee.vy + (dy*BeeAcc) DIV distance;
- BoundSpeed(Bee, BeeVel)
- END AccelerateBee;
- PROCEDURE Move(VAR i: Insect);
- BEGIN i.pos[0].x := i.pos[1].x + i.vx; i.pos[0].y := i.pos[1].y + i.vy
- END Move;
- PROCEDURE Draw(VAR i: Insect);
- BEGIN
- IF ~firstTime THEN Display1.Line(F, Display.white, i.pos[1].x, i.pos[1].y, i.pos[2].x, i.pos[2].y, Display.invert) END;
- Display1.Line(F, Display.white, i.pos[0].x, i.pos[0].y, i.pos[1].x, i.pos[1].y, Display.invert)
- END Draw;
- PROCEDURE DrawSwarm;
- VAR i: INTEGER;
- BEGIN
- i := 0;
- WHILE i < NrWasps DO
- Age(Wasps[i]); AccelerateWasp(Wasps[i]); Move(Wasps[i]); ReflectWasp(Wasps[i]); Draw(Wasps[i]); INC(i)
- END;
- i := random() MOD NrBees; Bees[i].vx := Bees[i].vx + Rand(3); (* change a random bee *)
- i := random() MOD NrBees; Bees[i].vy := Bees[i].vy + Rand(3);
- i := 0;
- WHILE i < NrBees DO
- Age(Bees[i]); AccelerateBee(Bees[i]); Move(Bees[i]); Draw(Bees[i]); INC(i)
- END
- END DrawSwarm;
- PROCEDURE GetPar(VAR S: Texts.Scanner; lbound, ubound, default: INTEGER; VAR val: INTEGER; VAR list: BOOLEAN);
- BEGIN
- IF list THEN
- IF S.class = Texts.Int THEN
- IF S.i < lbound THEN val := lbound ELSIF S.i < ubound THEN val := SHORT(S.i) ELSE val := ubound END
- ELSE
- list := FALSE; val := default
- END;
- Texts.Scan(S)
- ELSE
- val := default
- END
- END GetPar;
- PROCEDURE Start*;
- VAR msg: Viewers.ViewerMsg; S: Texts.Scanner; T: Texts.Text; pos, t, dummy: LONGINT; list: BOOLEAN;
- BEGIN
- Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S);
- IF (S.class = Texts.Char) & (S.c = "^") THEN
- Oberon.GetSelection(T, pos, dummy, t);
- IF t >= 0 THEN Texts.OpenScanner(S, T, pos); Texts.Scan(S) END
- END;
- list := TRUE; GetPar(S, 1, MaxWasps, 2, NrWasps, list); GetPar(S, 1, MaxBees, 100, NrBees, list); GetPar(S, 2, 20, 5, WaspAcc, list);
- GetPar(S, 1, 19, 3, BeeAcc, list); GetPar(S, 0, 20, 5, Delay, list);
- InitSwarm;
- msg.id := Viewers.suspend; Viewers.Broadcast(msg);
- Display.ReplConst(Display.black, 0, 0, Display.Width, Display.Height, Display.replace);
- WHILE Input.Available() = 0 DO
- DrawSwarm; Wait(Delay); firstTime := FALSE
- END;
- msg.id := Viewers.restore; Viewers.Broadcast(msg)
- END Start;
- END Swarm.Start 5 200 5 3 20
- (* Parameters: number of wasps, number of bees, wasp acceleration, bee acceleration, delay between steps (Input.Tick's) *)
- Swarm.Start
- System.State Swarm
-